package com.fjec.common.protocol;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fjec.common.enums.EnumSysCode;
import lombok.Builder;
import lombok.Data;

import java.util.LinkedHashMap;
import java.util.Map;

@Data
@Builder
public class JsonResult {

    /*--------------------------------------------
     |             C O N S T A N T S             |
    ============================================*/
    public transient static final JsonResult SUCCESS = JsonResult.builder()
            .success(true)
            .code(EnumSysCode.SUCCESS.getCode())
            .message(EnumSysCode.SUCCESS.getMsg())
            .build();

    public transient static final JsonResult FAILURE = JsonResult.builder()
            .success(false)
            .code(EnumSysCode.FAILURE.getCode())
            .message(EnumSysCode.FAILURE.getMsg())
            .build();

    public static JsonResult.JsonResultBuilder success() {
        return JsonResult.builder()
                .success(true)
                .code(EnumSysCode.SUCCESS.getCode())
                .message(EnumSysCode.SUCCESS.getMsg());
    }

    public static JsonResult.JsonResultBuilder failure() {
        return JsonResult.builder()
                .success(false)
                .code(EnumSysCode.FAILURE.getCode())
                .message(EnumSysCode.FAILURE.getMsg());
    }

    /*--------------------------------------------
    |    I N S T A N C E   V A R I A B L E S    |
    ============================================*/
    @Builder.Default
    private Boolean success = Boolean.TRUE;

    @JsonInclude(JsonInclude.Include.ALWAYS)
    private Object data;

    @Builder.Default
    private Long total = 0L;

    private String message;

    private String code;

    private String traceId;

    private Map<String, Object> other;

    private boolean hashMore;

    /*--------------------------------------------
    |         C O N S T R U C T O R S           |
    ============================================*/

    public JsonResult(Boolean success, Object data, Long total,
                      String message, String code, String traceId,
                      Map<String, Object> other, boolean hashMore) {
        this.success = success;
        this.data = data;
        this.total = total;
        this.message = message;
        this.code = code;
        this.traceId = traceId;
        this.other = other;
        this.hashMore = hashMore;
    }

    /*--------------------------------------------
        |               M E T H O D S               |
        ============================================*/
    public JsonResult putKeyValue(String key, Object value) {
        if (other == null) {
            this.other = new LinkedHashMap<String, Object>();
        }
        this.other.put(key, value);
        return this;
    }

    public JsonResult putKeyValueMap(Map<String, Object> keyValueMap) {
        if (other == null) {
            this.other = new LinkedHashMap<String, Object>();
        }
        this.other.putAll(keyValueMap);
        return this;
    }

    @Override
    public String toString() {
        return "{" +
                "\"success\": " + success +
                ", \"total\": " + total +
                ", \"message\": \"" + message + "\"" +
                ", \"data\": \"" + data + "\"" +
                ", \"code\": \"" + code + "\"" +
                ", \"traceId\": \"" + traceId + "\"" +
                '}';
    }
}
